package com.hfzy.ihk.web.ivr.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.facade.ivr.entity.NumBinding;
import com.hfzy.ihk.facade.ivr.enums.CallInSource;
import com.hfzy.ihk.web.ivr.constant.Constants;
import com.hfzy.ihk.web.ivr.constant.RedisKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * Created by Administrator on 2019/5/23.
 */
@Component
public class NumBindingBiz {

    private static final Logger logger = LoggerFactory.getLogger(NumBindingBiz.class);

    @Value("${getNumBinding.http.url}")
    private String numBindingUrl;

    @Autowired(required = false)
    RestTemplate restTemplate;

    @Autowired
    RedisTemplate redisTemplate;

    public Map<String, String> getLastCallUserNum(String showNum, String telNo, CallInSource callInSource) {
        //从redis中找到该主显号打给该电话的最后一个用户的id
        //TODO:
        //{"dataId":"27986787","userId":"41459"}
        Map<String,String> redisMap = getLastCall(showNum, telNo);
        logger.info("getLastCall result:{}", JSONObject.toJSONString(redisMap));
        Long userId = null;

        if(Constants.NEGATIVE_STR.equals(redisMap.get("userId"))){//被呼出过，才能呼入
            return null;
        }

        if(redisMap != null && redisMap.get("userId") != null) {
            userId = Long.valueOf(redisMap.get("userId"));
        }

        Map<String, String> resultMap = null;
//        Integer userId = getLastCallUser(showNum,telNo);
        //如果最后一次通话的用户存在
        if(userId !=null && userId.intValue() > 0){
            //如果用户id存在，则找到他的绑定记录
            NumBinding numBinding = getByZyUserId(Integer.valueOf(userId.toString()));
            //如果存在绑定记录，则按照定好的规则，找到实际的号码
            if(numBinding != null){
                logger.info("getLastCallUserNum->numBindingDao.getByZyUserId is not null,userId:{}",userId);
                //通过绑定记录获得号码
                if(showNum.startsWith("0757")){//佛山做特殊
                    numBinding.setCity(9);//设一个比较大的值，避免跟表中原来的不准的city冲突
                }
                resultMap = getMapByNumBinding(numBinding,callInSource);
            }
        }else {//如果最后一次通话的用户不存在，则返回空
            logger.info("getLastCallUserNum->getLastCall from redis is null,getNumByShowNum{} now. ",showNum);
            resultMap = null;
        }

        if(resultMap != null) {
            //置业的dataId
            resultMap.put("dataId", redisMap.get("dataId"));
            resultMap.put("cityId", redisMap.get("cityId"));
            logger.info("getLastCallUserNum result:{}",JSONObject.toJSONString(resultMap));
        }
        return resultMap;
    }

    public Map<String, String> getLastCall(String showNum, String telNo) {
        String field1 = RedisKey.LAST_CALL_INFO_USER_ID;
        String field2 = RedisKey.LAST_CALL_INFO_DATA_ID;
        String field3 = RedisKey.LAST_CALL_INFO_CITY_ID;

        List<String> redisValues = new ArrayList<>();
        if(StringTools.isNotNull(showNum)){
            redisValues = redisTemplate.opsForHash().multiGet(RedisKey.createLastCallInfo(showNum,telNo), Arrays.asList(field1,field2,field3));
        }else{
            redisValues = redisTemplate.opsForHash().multiGet(RedisKey.createFsLastCallInfo(telNo), Arrays.asList(field1,field2,field3));
        }


        Map<String, String> map = new HashMap<String, String>();

        if(redisValues == null || redisValues.isEmpty()) {
            map.put("userId", Constants.NEGATIVE_STR);//-1
            map.put("dataId", Constants.NEGATIVE_STR);
            map.put("cityId", Constants.NEGATIVE_STR);
        }else {
            if(redisValues.get(0) == null)
                map.put("userId", Constants.NEGATIVE_STR);//-1
            else
                map.put("userId", redisValues.get(0));

            if(redisValues.get(1) == null)
                map.put("dataId", Constants.NEGATIVE_STR);
            else
                map.put("dataId", redisValues.get(1));
            if(redisValues.get(2) == null)
                map.put("cityId", Constants.NEGATIVE_STR);
            else
                map.put("cityId", redisValues.get(2));
        }
        return map;
    }

    /**
     *
     * @param numBinding
     * @return targetCallPhone:被叫号码
     *         userId:座席ID
     *         phoneType:座机还是手机(telno座机/phone手机)
     */
    private Map getMapByNumBinding(NumBinding numBinding,CallInSource callInSource){
        Map<String, String> resultMap = new HashMap<String, String>();
        if (numBinding.getValid()) {
            String userIdStr = String.valueOf(numBinding.getZyUserId());
            resultMap.put("userId", userIdStr);
            if((StringTools.isNotempty(numBinding.getCity())&&numBinding.getCity()==9)||CallInSource.FREESWITCH.equals(callInSource)){ //阿里云佛山呼入直接呼入到手机 或者fs进来直接拿手机号码
                resultMap.put("targetCallPhone", numBinding.getMyPhone());
                resultMap.put("phoneType", "phone");
            }else{
                boolean isUserBusy = Constants.TRUE.equals(redisTemplate.opsForHash().get(RedisKey.USER_BUSY,userIdStr));
                logger.info("income userId: {} isBusy:{}", userIdStr, isUserBusy);
                if (!isUserBusy && numBinding.getActive()) {
                    resultMap.put("targetCallPhone", numBinding.getMyTelno());
                    resultMap.put("phoneType", "telno");

                } else {
                    resultMap.put("targetCallPhone", numBinding.getMyPhone());
                    resultMap.put("phoneType", "phone");
                }
            }
            //用来临时解决阿里呼入不能用95号码的问题czs
            resultMap.put("userTel",numBinding.getMyPhone());

        } else {
            NumBinding managerBinding = getManagerBinding(numBinding);
            resultMap.put("targetCallPhone", managerBinding==null ? "":managerBinding.getMyPhone());
            resultMap.put("userId", managerBinding==null ? "":managerBinding.getZyUserId() + "");
            resultMap.put("phoneType", "phone");

            //用来临时解决阿里呼入不能用95号码的问题czs
            resultMap.put("userTel",managerBinding.getMyPhone());//用来临时解决阿里呼入不能用95号码的问题
        }

        return resultMap;
    }

    private NumBinding getManagerBinding(NumBinding numBinding) {
        //如果没有上级的id，则返回null
        if (numBinding.getManagerId() == 0) {
            return null;
        }
        NumBinding item = getByZyUserId(numBinding.getManagerId());
        if (item == null) {
            //如果上级的记录不存在，则返回null
            return null;
        }
        if (item.getValid()) {
            //如果其上级在职，则返回该记录
            return item;
        } else {
            //如果已离职，则递归找
            return getManagerBinding(item);
        }
    }

    /**呼入转接号码
     *
     * @param sessionId
     * @param mainCallPhone
     * @param targetCallPhone
     * @param showNum
     * @param pId 东进 进程ID
     */
    public void transNum(String sessionId, String mainCallPhone, String targetCallPhone, String showNum, String pId) {
        logger.debug("transNum-> sesssionId:{} mainCallPhone:{} targetCallPhone{} showNum:{} pId:{}", sessionId, mainCallPhone, targetCallPhone, showNum, pId);
        String type = "1";
        String isRecord = "1";
        //东进线路呼出，去掉020，但异地区号不需要处理；异地手机则前面+0
        targetCallPhone = confirmPhone(targetCallPhone);
        int stringListSize = sessionId.length() +
                mainCallPhone.length() + targetCallPhone.length() +
                type.length() + isRecord.length() + pId.length();
        String inStr =
                "<CTMSG>" +
                        "<CLASS>4</CLASS>" +
                        "<TYPE>199</TYPE>" +
                        "<MID>1</MID>" +
                        "<CMD>-1</CMD>" +
                        "<PID>0</PID>" +
                        "<UserMsgType>102</UserMsgType>" +
                        "<IntItems>0;1;2;3;4;5;6;7;8;9</IntItems>" +
                        "<StringListSize>" + stringListSize + "</StringListSize>" +
                        "<Str0>" + sessionId + "</Str0>" +
                        "<Str1>" + mainCallPhone + "</Str1>" +
                        "<Str2>" + type + "</Str2>" +
                        "<Str3>" + targetCallPhone + "</Str3>" +
                        "<Str4>" + isRecord + "</Str4>" +
                        "<Str5></Str5>" +
                        "<Str6></Str6><Str7></Str7><Str8></Str8>" +
                        "<Str9>" + pId + "</Str9>" +
                        "</CTMSG>";
        logger.debug(inStr);
        //SocketHandler.getInstance().sendMessage(inStr);
    }

    /**
     *
     * 东进线路呼出，去掉020，但异地区号不需要处理；异地手机则前面+0
     * @param phone
     * @return phone
     */
    public String confirmPhone(String phone) {
        //东进线路呼出，去掉020，但异地区号不需要处理
        try {
            if (phone.startsWith("020")) {
                phone = phone.substring(3, phone.length());
            } else if (phone.startsWith("1")) { //异地手机需要在前面+0
                String pre7 = phone.substring(0, 7);
                Object city = redisTemplate.opsForHash().get(RedisKey.PHONE_LOCATION + pre7, "city");
                //不是广州，或者为空时，视为异地
                if (!"广州".equals(city.toString())) {
                    phone = "0" + phone;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return phone;
    }

    public NumBinding getByZyUserId(Integer userId){
        String url = numBindingUrl + "?userId="+userId;
        Map<String,Object> resultMap =  restTemplate.getForObject(url,Map.class);
        NumBinding  numBinding = null;
        if(!resultMap.isEmpty()&&"1".equals(resultMap.get("code").toString())){
            numBinding = JSONObject.parseObject(JSONObject.toJSONString(resultMap.get("data")), NumBinding.class);
        }
        return numBinding;
    }
}
